package nl.ypmits.utils.as3.stage {
	import nl.ypmits.utils.as3.stage.event.SimpleStageEvent;
	import nl.ypmits.utils.as3.stage.input.SimpleStageInput;

	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageDisplayState;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.system.fscommand;

	/**
	 * @author Dave Lenz (based on Merten Snijders' StageResize classes)
	 */
	public class SimpleStage extends EventDispatcher {
		private static var _instance : SimpleStage;
		
		public static const QUALITY_MEDIUM : String = StageQuality.MEDIUM;
		public static const QUALITY_HIGH : String = StageQuality.HIGH;
		private static var CANVAS_WIDTH : int = 0;
		private static var CANVAS_HEIGHT : int = 0;
		private var input : SimpleStageInput;
		private var _upperLeftLock : Boolean = false;		private var _fullscreen : Boolean;

				public function SimpleStage() 		{
			_instance = this;
		}
				public static function get instance() : SimpleStage {
			if (!_instance) _instance = new SimpleStage( );
			return _instance;
		}
		
		
		public function toggleFullscreen() : void {
			if( input.stage.displayState == StageDisplayState.FULL_SCREEN ) {
				input.stage.displayState = StageDisplayState.NORMAL;
			} else {
				input.stage.displayState = StageDisplayState.FULL_SCREEN;
			}
		}

		
		public function build( _i : SimpleStageInput ) : void 
		{
			input = _i;
			input.validate( );
			
			CANVAS_WIDTH = input.width;
			CANVAS_HEIGHT = input.height;
			
			trace("input: "+input);
			trace("input.stage: "+input.stage);
			trace("input.stage.scaleMode: "+input.stage.scaleMode);
			trace("input.stagescalemode: "+input.stagescalemode);
			trace("");
			input.stage.scaleMode = input.stagescalemode;
			if (input.stagealign != null) input.stage.align = input.stagealign;
			if (input.fullscreen) fscommand( "fullscreen", "true" );
			if (input.upperleftlock) _upperLeftLock = input.upperleftlock;
			addStageListeners( );
		}
				private function hasRelative() : Boolean 
		{
			return input.minimumheight > input.height && input.minimumwidth > input.width;
		}
				private function removeStageListeners() : void 
		{
			input.stage.removeEventListener( Event.RESIZE, onStageResize );	
			input.stage.removeEventListener( Event.ACTIVATE, onStageActivate );
			input.stage.removeEventListener( Event.DEACTIVATE, onStageDeActivate );
		}
				private function addStageListeners() : void 
		{
			input.stage.addEventListener( Event.RESIZE, onStageResize );	
			input.stage.addEventListener( Event.ACTIVATE, onStageActivate );
			input.stage.addEventListener( Event.DEACTIVATE, onStageDeActivate );
		}
				public function getCanvasHeight() : int 
		{
			return CANVAS_HEIGHT;
		}
				public function getCanvasWidth() : int 
		{
			return CANVAS_WIDTH;
		}
				private function onStageResize( e : Event ) : void 
		{
			
			// TODO only when 
			if (_upperLeftLock) 
			{			
				var heightToSmall : Boolean = input.stage.stageHeight < input.height;
				var widthToSmall : Boolean = input.stage.stageWidth < input.width;
				
				if ( heightToSmall && widthToSmall ) 
				{
					if (input.stage.align != StageAlign.TOP_LEFT ) 
					{
						input.stage.align = StageAlign.TOP_LEFT;
					}
				} else if ( heightToSmall ) 
				{
					if (input.stage.align != StageAlign.TOP ) 
					{
						input.stage.align = StageAlign.TOP;
					}
				} else if ( widthToSmall ) 
				{
					if (input.stage.align != StageAlign.LEFT ) 
					{
						input.stage.align = StageAlign.LEFT;
					}
				} 
				else 
				{
					if (input.stage.align != input.stagealign) 
					{
						input.stage.align = input.stagealign;
					}
				}
			}
			
			// TODO check percentages
			var r : SimpleStageEvent = new SimpleStageEvent( SimpleStageEvent.UPDATE );
			r.height = getHeight( );
			r.width = getWidth( );
			
			if (hasRelative( )) 
			{
				
				var span : Number;
				
				span = r.width - input.width;
				r.offsetWidth = input.minimumwidth - input.width;
				r.percentageHorizontal = trimPercentage( span / r.offsetWidth );
				
				span = r.height - input.height;
				r.offsetHeight = input.minimumheight - input.height;
				r.percentageVertical = trimPercentage( span / r.offsetHeight );
			}
			
			dispatchEvent( r );
		}
				private function trimPercentage( _p : Number ) : Number 
		{
			if (_p > 1) return 1;
			if (_p < 0) return 0;
			return _p;
		}
				public function getStage() : Stage 
		{
			try {
				return input.stage;
			}
			catch(e : *) 			{
				trace( "ERROR! there is no stage... please set the stage with 'setStage' or by using the 'SimpleStageInput' in the 'build' function" );
			}
			return null;
		}
				public function getHeight() : Number 
		{
			return input.stage.stageHeight;
		}
				public function getWidth() : Number 
		{
			return input.stage.stageWidth;
		}
				private function onStageDeActivate( e : Event ) : void 
		{
			var r : SimpleStageEvent = new SimpleStageEvent( SimpleStageEvent.BLUR );
			dispatchEvent( r );
		}
				private function onStageActivate( e : Event ) : void 
		{
			var r : SimpleStageEvent = new SimpleStageEvent( SimpleStageEvent.FOCUS );
			dispatchEvent( r );
		}
				public function dispose() : void 
		{
			removeStageListeners( );	
		}
				public function setQuality( _q : String) : void 
		{
			getStage( ).quality = _q;
		}
				public function get fullscreen() : Boolean
		{
			return _fullscreen;
		}
				public function set fullscreen(fullscreen : Boolean) : void
		{
			_fullscreen = fullscreen;
			if(fullscreen) 			{
				try {
					getStage( ).displayState = StageDisplayState.FULL_SCREEN;
				} catch(e : *) 
				{
					trace( "ERROR!... Cannot toggle to fullscreen. Check the html or make sure you're not in the Eclipse(SWT)-environment!" );
				}
			} 			else 			{
				getStage( ).displayState = StageDisplayState.NORMAL;
			}
		}
	}
}

